梦入琼楼寒有月,行过石树冻无烟

Vue.js createApp and RootComponent at DataProperty

RootComponent

在 Vue 3.0 中,每个应用的创建都是通过 createApp 函数进行创建一个新的应用:

1
2
3
const app = Vue.createApp({
// code
})

上述这种方法可以更加明显的表示出 createApp 函数的作用,但 Vue3.0 中还有另一种方法更加遵循 MVVM 模型。

尽管 Vue 的设计没有完全遵循,但设计收到了他的启发,因此在文档中也会使用 vm 来作为 ViewModel 的缩写来表示组件实例。

在大多数真实应用中,这些语法都是层层嵌套的,为此为了一个可重用的组件树,还提供了 根组件 的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
{{message.hey}}
</div>
<script>
const RootComponent = {
data() {
return {
message: {
hey: 'hey,world!'
}
}
}
}
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')
</script>

MVVM 架构的核心是通过数据进行驱动,即 ViewModel,通过 ViewModel 将 View 和 Model 进行关联映射,更加通俗的说法 ViewModel 就是一个负责转换 Model 中的数据对象,使得数据对象更加便与管理和使用,也就是双向绑定。

当用户操作 View 时,ViewModel 就会监听到改变后通知 Model 发生了改变,如果 Model 改变则 View 也会改变。

生命周期

当使用 createApp 时,会初始化事件和生命周期,之后创建将模板渲染函数并将 app.$el 添加到 el 安装,当数据发生变化时重新渲染并更新,最后当 app.unmount() 被调用时将会卸载该应用。

在初始化事件和生命周期之前还会初始化注射(ingections)以及响应式(reactivify)

Data Property

组件中的 data 函数在 Vue 创建新的实例的过程中将会被调用,他返回的是一个对象,之后 Vue 会通过相应性系统将其包裹,并以 $data 的形式存储在组件实例中,该函数的任何属性也会直接通过他来暴露出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
{{message}}
</div>
<script>
const app = Vue.createApp ({
data() {
return {
message: 'hey,world!',
}
}
})
const vm = app.mount('#app')
console.log(vm.message) // => hey,world!
vm.message = 'hey,message!'
console.log(vm.$data.message) // => hey,message!
</script>

这些属性在实例创建时进行添加,所以需要保证他们在 data 返回的对象中,他还支持属性使用 null 以及 undefined 或其他站位值。

Vue 使用的是 $ 前缀来通过组件实例所暴露自己的内置 API,对于内部还提供了 _ 前缀。

直接将不包含 data 中的属性添加到实例中是可行的,但由于睡醒那个不再背后的响应式,因此 Vue 相应性系统不会自动跟踪,也就是说他无法自动更新。

methods

methods 选项向组件实例添加方法,主要用于包含所需方法对象,Vue 自动将 methods 绑定为 this,以便于他始终指向组件实例。

需要注意的是在定义 methods 时应避免使用箭头函数,这回阻止 Vue 绑定恰当的 this 指向。

通常 this 指向该实例的本身

在模板指令中通常 方法(methods) 会和其他的属性在组件模板中被访问,这通常是事件监听,如 v-on 指令 (他有很多的 methods)

Lodash

Lodash 是遵循 MIT 开源协议所发布的,一致性、模块化、高性能的 JavaScript 实用工具库。

本文主要演示下 _.debounce(func,[wait=0],[options={}]) 函数以及 Vue Data Property 的 “相应性” 的使用。

_.debounce 函数主要的作用就是延迟 functionwait 自上次调用 debounced 函数以来经过多少毫秒后。

可参考下 Lodash doc: https://www.lodashjs.com/docs/lodash.debounce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="app">
<button @click="toclick">up go</button>
<p>{{message}}</p>
</div>
<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>
<script>
const app = Vue.createApp ({
data() {
return {
toclick: _.debounce(function () {
vm.message = 'hey,lodash'
}, 1000),
message: 'hey,world!'
}
}
})
const vm = app.mount('#app')
</script>

如上述的例子中主要通过 lodash 所提供的 _.debounce 函数延迟 1ms 来改变 message 属性的值。当数据发生变化时 DOM 将会重新渲染并更新。

⬅️ Go back